/**
 * Copyright (C), 2015-2018, XXX有限公司
 * FileName: ApiResponsseIntercept
 * Author:   sjkyll
 * Date:     2018-07-27 13:06
 * Description:
 * <author>          <time>          <version>          <desc>
 * 作者姓名         修改时间           版本号            描述
 */
package com.cdqidi.smsservice.inceptor;

import com.cdqidi.smsservice.dto.AjaxResult;
import com.cdqidi.smsservice.dto.ApiLogin;
import com.cdqidi.smsservice.exception.ApiException;
import com.cdqidi.smsservice.domain.CpConfig;
import com.cdqidi.smsservice.service.CacheService;
import com.cdqidi.smsservice.service.CpConfigService;
import com.cdqidi.smsservice.util.ApiLoginUtil;
import com.cdqidi.smsservice.util.IpHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

/**
 * 〈验证请求是否合法〉<br>
 *
 * @author sjkyll
 * @create 2018-07-27 13:06
 * @since 1.0.0
 */
@Component
public class AuthProcessIntercept implements HandlerInterceptor {
    private final CpConfigService cpConfigService;
    private final CacheService cacheService;

    @Autowired
    public AuthProcessIntercept(CpConfigService cpConfigService, CacheService cacheService) {
        this.cpConfigService = cpConfigService;
        this.cacheService = cacheService;
    }

    /**
     * 在整个请求结束之后被调用，也就是在DispatcherServlet 渲染了对应的视图之后执行（主要是用于进行资源清理工作）
     *
     * @param request
     * @param response
     * @param object
     * @param exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) {
        ApiLoginUtil.removeThreadLocalApiConfig();
    }

    /**
     * 请求处理之后进行调用，但是在视图被渲染之前（Controller方法调用之后）
     *
     * @param request
     * @param response
     * @param object
     * @param modelAndView
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView modelAndView) {
    }

    /**
     * 在请求处理之前进行调用（Controller方法调用之前),只有返回true才会继续向下执行，返回false取消当前请求
     *
     * @param request
     * @param response
     * @param object
     * @return
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws ApiException {
        String ipAddr = IpHelper.getIpAddr(request);
        String appId = request.getParameter("appid");
        String acceeToken = request.getParameter("access_token");
        if (null == appId || "".equals(appId)) {
            throw new ApiException(AjaxResult.filedError("appid不能为空"));
        }
        Optional<CpConfig> cpConfig = cacheService.getCpConfig(appId);
        if (cpConfig.isPresent()) {
            final String ipAddress = cpConfig.get().getIpAddress();
            if (null != ipAddress && !"".equals(ipAddress)) {
                boolean isExists = false;
                String[] ips = ipAddress.split(",");
                for (String ip : ips) {
                    if (ip.equals(ipAddr)) {
                        isExists = true;
                        break;
                    }
                }
                if (!isExists) {
                    throw new ApiException(AjaxResult.filedError("ip地址非法： " + ipAddr));
                }
            }
            Boolean isValidate = cpConfig.get().getValidate();
            //是否验证access_token
            if (null!=isValidate&&isValidate) {
                if (null == acceeToken || "".equals(acceeToken)) {
                    throw new ApiException(AjaxResult.filedError("access_token不能为空"));
                }
                isValidate = cpConfigService.isAccessToken(acceeToken);
                if(!isValidate){
                    throw new ApiException(AjaxResult.accessTokenError("access_token不存在"));
                }
            }

        } else {
            throw new ApiException(AjaxResult.filedError("appid未注册"));
        }
        ApiLogin login = new ApiLogin();
        login.setIp(ipAddr);
        login.setAppId(appId);
        ApiLoginUtil.setThreadLocalApiConfig(login);
        return true;
    }

}